#include <algorithm>
#include <cstring>
#include <memory>
#include <models/PrimitiveDataManager.h>
#include <stdexcept>

PrimitiveDataManager::PrimitiveDataManager()
{
    memset(&mem_spaces_, 0, sizeof(mem_spaces_));
    for (uint16_t i = 0; i < max_variables; i++) {
        available_positions_.push_back(i);
    }
}

PrimitiveData& PrimitiveDataManager::get_primitive_data(uint16_t pos)
{
    if (pos >= max_variables) {
        throw std::out_of_range("Invalid position");
    }
    return mem_spaces_[pos];
}

void PrimitiveDataManager::set_primitive_data(uint16_t pos, const PrimitiveData& data)
{
    if (pos >= max_variables) {
        return;
    }
    mem_spaces_[pos] = data;
}

void PrimitiveDataManager::set_primitive_data(uint16_t pos, int64_t i_part, uint16_t d_part,
    time_t update_time, uint16_t milliseconds = 0)
{
    PrimitiveData data;
    data.i_part = i_part;
    data.d_part = d_part;
    data.update_time = update_time;
    data.milliseconds = milliseconds;
    set_primitive_data(pos, data);
}

uint16_t PrimitiveDataManager::get_available_position(const std::string& sn)
{
    if (available_positions_.empty()) {
        throw std::runtime_error("No available positions");
    }

    auto it = std::find(variable_sns_.begin(), variable_sns_.end(), sn);
    if (it == variable_sns_.end()) {
        uint16_t pos = available_positions_.front();
        available_positions_.pop_front();
        return pos;
    }

    throw std::runtime_error("SN already exists");
}